import { CircleShape } from "../../lib/kgame/d2/shape/CircleShape";
import { ECSCmp } from "../../lib/kgame/ecs/ECSCmp";
import { IVec2 } from "../../lib/kgame/util/Defined";
import { MathUtil } from "../../lib/kgame/util/MathUtil";
import { ColliderCmp } from "./ColliderCmp";
import { MoveCmp } from "./MoveCmp";
import { SnakeBodyCmp } from "./SnakeBodyCmp";
import { SnakeCmp } from "./SnakeCmp";

/**
 * 蛇路径点
 */
export interface ISnakePos extends IVec2 {
    /** 旋转角度 */
    rot: number
    /** 下一路径点 */
    next?: ISnakePos;
}

/**
 * 蛇头组件
 */
export class SnakeHeadCmp extends ECSCmp {

    snake: SnakeCmp;
    /** 食物碰撞器 */
    foodCollider: ColliderCmp<CircleShape>;
    /** 蛇碰撞器 */
    snakeCollider: ColliderCmp<CircleShape>;
    /** 幽灵时间(无碰撞) */
    ghostTime: number = 0;

    /**
    * 初始化蛇头组件
    * @param move 移动组件
    * @param foodCollider 食物碰撞器
    * @param snakeCollider 蛇碰撞器
    * @param colors 蛇身十进制颜色 数组形式代表多节颜色循环
    * @param score 起始分数
    */
    onCreate(
        snake: SnakeCmp,
        move: MoveCmp,
        foodCollider: ColliderCmp<CircleShape>,
        snakeCollider: ColliderCmp<CircleShape>,
        colors?: number[],
        score = 0,
        ghostTime = 3
    ) {
        this.snake = snake;
        this.move = move;
        this.foodCollider = foodCollider;
        this.snakeCollider = snakeCollider;
        if (colors == undefined) {
            colors = [];
            let len = this.scene.rand.weight([[1, 250], [2, 100], [3, 50], [4, 20], [5, 15], [6, 10], [7, 5], [8, 1]]);
            while (--len >= 0) {
                colors.push(this.scene.rand.color());
            }
        }
        this.colors = colors;
        this.ghostTime = ghostTime;
        this.snakeCollider.enable = this.ghostTime <= 0;
        this.updateAttr(score);
        this.path = this.pathTail = { x: this.pos.x, y: this.pos.y, rot: this.entity.rot };
        this.sprintScore = 0;
        return this;
    }

    protected onClear(): void {
        this.snake = null;
        this.move = null;
        this.foodCollider = null;
        this.snakeCollider = null;
        this.colors = null;
        this.bodys.length = 0;
    }

    // ============ 属性 ============

    protected _score: number;
    /** 属性有变化 */
    protected _attrDirty: boolean;

    /** 分数 决定蛇的属性 */
    get score() {
        return this._score;
    }

    set score(v: number) {
        this._score = v;
        this._attrDirty = true;
    }

    /** 蛇身十进制颜色 数组形式代表多节颜色循环 */
    colors: number[]
    /** 大小 */
    size: number;
    /** 半径 */
    radius: number;
    /** 蛇身间隔 */
    space: number;
    /** 蛇身长度 */
    len: number;
    /** 移动组件(移动速度,转弯速度) */
    move: MoveCmp
    /** 冲刺消耗掉的分数 (累计一定就变成食物生成出去) */
    sprintScore = 0;

    /**
     * 如果分数有变化，更新蛇的属性
     */
    updateAttr(score?: number) {
        if (score !== undefined) {
            this.score = score;
            this._attrDirty = true;
        }

        if (this._attrDirty) {
            this._attrDirty = false;
            this.size = XSnakeMisc.initSize + (this.score / 250 + Math.pow(this.score, 0.2));
            this.space = this.size * XSnakeMisc.initSpace;
            this.len = XSnakeMisc.initLen + this.score / (this.size - this.space) >> 0;
            this.move.moveSpd = XSnakeMisc.initMoveSpd + this.size;
            const circleDis = this.size * Math.PI;
            this.move.rotSpd = this.move.moveSpd / ((1.25 + XSnakeMisc.rotSizeRate) * circleDis / MathUtil.PI2);
            this.radius = this.size / 2;
            this.foodCollider.shape.radius = this.radius * 3;
            this.snakeCollider.shape.radius = this.radius - 3;
        }
    }

    // ============ 蛇身 ============

    /** 蛇身 */
    bodys: SnakeBodyCmp[] = [];
    /** 蛇尾 */
    get tail() {
        return this.bodys[this.bodys.length - 1];
    }
    /** 蛇路径 */
    path: ISnakePos;
    /** 蛇路径尾 */
    pathTail: ISnakePos;
    /** 已回收的蛇路径(用于循环使用对象) */
    pathRecy: ISnakePos;


}